package com.zenithmind.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.mall.mapper.ProductCategoryMapper;
import com.zenithmind.mall.pojo.dto.ProductCategoryDTO;
import com.zenithmind.mall.pojo.entity.ProductCategory;
import com.zenithmind.mall.pojo.vo.ProductCategoryVO;
import com.zenithmind.mall.service.ProductCategoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品分类服务实现
 * 
 * @author ZenithMind Team
 * @since 2025-06-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMapper, ProductCategory> implements ProductCategoryService {

    @Override
    public List<ProductCategoryVO> getCategoryTree() {
        // 查询所有启用的分类
        LambdaQueryWrapper<ProductCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductCategory::getIsDeleted, 0)
               .eq(ProductCategory::getStatus, 1)
               .orderByDesc(ProductCategory::getCreateTime);
        
        List<ProductCategory> allCategories = list(wrapper);
        
        // 转换为VO并构建树形结构
        List<ProductCategoryVO> categoryVOs = allCategories.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        return buildCategoryTree(categoryVOs, "0");
    }

    @Override
    public List<ProductCategoryVO> getCategoriesByParentId(String parentId) {
        LambdaQueryWrapper<ProductCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductCategory::getParentId, parentId)
               .eq(ProductCategory::getIsDeleted, 0)
               .eq(ProductCategory::getStatus, 1)
               .orderByDesc(ProductCategory::getCreateTime);
        
        List<ProductCategory> categories = list(wrapper);
        return categories.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createCategory(ProductCategoryDTO categoryDTO) {
        // 验证父分类是否存在
        if (StringUtils.hasText(categoryDTO.getParentId()) && !"0".equals(categoryDTO.getParentId())) {
            ProductCategory parentCategory = getById(categoryDTO.getParentId());
            if (parentCategory == null) {
                throw new BusinessException("父分类不存在");
            }
        }

        // 检查同级分类名称是否重复
        LambdaQueryWrapper<ProductCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductCategory::getName, categoryDTO.getName())
               .eq(ProductCategory::getParentId, categoryDTO.getParentId() != null ? categoryDTO.getParentId() : "0")
               .eq(ProductCategory::getIsDeleted, 0);
        
        if (count(wrapper) > 0) {
            throw new BusinessException("同级分类名称已存在");
        }

        ProductCategory category = new ProductCategory();
        BeanUtils.copyProperties(categoryDTO, category);
        
        // 设置默认值
        if (category.getParentId() == null) {
            category.setParentId("0");
        }
        if (category.getStatus() == null) {
            category.setStatus(1);
        }
        
        category.setCreateBy(UserContext.getUserId());
        
        if (!save(category)) {
            throw new BusinessException("创建分类失败");
        }
        
        log.info("创建商品分类成功: {}", category.getId());
        return category.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateCategory(String id, ProductCategoryDTO categoryDTO) {
        ProductCategory existCategory = getById(id);
        if (existCategory == null) {
            throw new BusinessException("分类不存在");
        }

        // 验证父分类是否存在
        if (StringUtils.hasText(categoryDTO.getParentId()) && !"0".equals(categoryDTO.getParentId())) {
            ProductCategory parentCategory = getById(categoryDTO.getParentId());
            if (parentCategory == null) {
                throw new BusinessException("父分类不存在");
            }
            
            // 不能将分类设置为自己的子分类
            if (id.equals(categoryDTO.getParentId())) {
                throw new BusinessException("不能将分类设置为自己的子分类");
            }
        }

        // 检查同级分类名称是否重复
        LambdaQueryWrapper<ProductCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductCategory::getName, categoryDTO.getName())
               .eq(ProductCategory::getParentId, categoryDTO.getParentId() != null ? categoryDTO.getParentId() : "0")
               .eq(ProductCategory::getIsDeleted, 0)
               .ne(ProductCategory::getId, id);
        
        if (count(wrapper) > 0) {
            throw new BusinessException("同级分类名称已存在");
        }

        ProductCategory category = new ProductCategory();
        BeanUtils.copyProperties(categoryDTO, category);
        category.setId(id);
        category.setUpdateBy(UserContext.getUserId());

        boolean result = updateById(category);
        if (result) {
            log.info("更新商品分类成功: {}", id);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteCategory(String id) {
        ProductCategory category = getById(id);
        if (category == null) {
            throw new BusinessException("分类不存在");
        }

        // 检查是否有子分类
        LambdaQueryWrapper<ProductCategory> childWrapper = new LambdaQueryWrapper<>();
        childWrapper.eq(ProductCategory::getParentId, id)
                   .eq(ProductCategory::getIsDeleted, 0);
        
        if (count(childWrapper) > 0) {
            throw new BusinessException("存在子分类，无法删除");
        }

        // TODO: 检查是否有商品使用该分类
        // 这里可以添加检查商品表的逻辑

        boolean result = removeById(id);
        if (result) {
            log.info("删除商品分类成功: {}", id);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteCategoriesBatch(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return true;
        }

        for (String id : ids) {
            deleteCategory(id);
        }
        return true;
    }

    @Override
    public ProductCategoryVO getCategoryById(String id) {
        ProductCategory category = getById(id);
        if (category == null) {
            throw new BusinessException("分类不存在");
        }
        return convertToVO(category);
    }

    @Override
    public List<ProductCategoryVO> getEnabledCategories() {
        LambdaQueryWrapper<ProductCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductCategory::getIsDeleted, 0)
               .eq(ProductCategory::getStatus, 1)
               .orderByDesc(ProductCategory::getCreateTime);
        
        List<ProductCategory> categories = list(wrapper);
        return categories.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    /**
     * 构建分类树
     */
    private List<ProductCategoryVO> buildCategoryTree(List<ProductCategoryVO> categories, String parentId) {
        List<ProductCategoryVO> tree = new ArrayList<>();
        
        for (ProductCategoryVO category : categories) {
            if (parentId.equals(category.getParentId())) {
                List<ProductCategoryVO> children = buildCategoryTree(categories, category.getId());
                category.setChildren(children);
                tree.add(category);
            }
        }
        
        return tree;
    }

    /**
     * 转换为VO
     */
    private ProductCategoryVO convertToVO(ProductCategory category) {
        ProductCategoryVO vo = new ProductCategoryVO();
        BeanUtils.copyProperties(category, vo);
        
        // 设置状态文本
        vo.setStatusText(category.getStatus() == 1 ? "启用" : "禁用");
        
        return vo;
    }
}
